<?php
class erpapi_caller{

    /**
     * CONFIG
     *
     * @var string
     **/
    private $__config = null;

    /**
     * RESULT
     *
     * @var string
     **/
    private $__result = null;

    public function set_config(erpapi_config $config)
    {
        $this->__config = $config;

        return $this;
    }

    public function set_result(erpapi_result $result)
    {
        $this->__result = $result;

        return $this;
    }


    /**
     * 异步请求
     *
     * @return void
     * @author 
     **/
    public function call($method,$params,$callback=array(),$title='',$time_out=10,$primary_bn='')
    {
        // 白名单
        if (false === $this->__config->whitelist($method)) {
            $response['rsp']       = 'fail';
            $response['err_msg']   = '接口被禁止';
            $response['res_ltype'] = 1;

            return $response;
        }

        // 记日志
        $apilogModel = app::get('ome')->model('api_log');
        $log_id = $apilogModel->gen_id();

        if ($callback['class'] && $callback['method']) {
            $callback['params']['log_id'] = $log_id;
            $callback['params']['obj_bn'] = $primary_bn;
        }

        // 请求
        $realtime = $callback ? false : true;
        $gzip     = isset($params['gzip']) ? $params['gzip'] : false; unset($params['gzip']);
        $rpc_id   = $params['rpc_id'] ? $params['rpc_id'] : null; unset($params['rpc_id']);



        $result = kernel::single('erpapi_rpc_caller')->set_timeout($time_out)
                                           ->set_realtime($realtime)
                                           ->set_config($this->__config)
                                           ->set_result($this->__result)
                                           ->set_callback($callback['class'], $callback['method'], $callback['params'])
                                           ->call($method, $params,  $rpc_id, $gzip);
                                           
        $result['msg'] = $result['err_msg'];
        $status = 'fail';
        if ($result['rsp'] == 'running') {
            $status = 'running';
        } elseif ($result['rsp'] == 'succ') {
            $status = 'success';
        }
        $msg = var_export($result,true);
        if(isset($msg{2048})) { //当返回结果大于2KB时，日记中不写结果
            $msg = $result['rsp'] == 'succ' ? '成功' : ($result['rsp'] == 'running' ? '运行中' : '失败');
        }
        // 如果是异常，超时重新加队列
        if ($realtime === false && $result['rsp'] == 'fail') {
            $failApiModel = app::get('erpapi')->model('api_fail');
            $failApiModel->publish_api_fail($method,$callback['params'],$result);
        }

        $logsdf = array(
            'log_id'        => $log_id,
            'task_name'     => $title,
            'status'        => $status,
            'worker'        => '',
            'params'        => serialize(array($method, $params, $callback)),
            'msg'           => $msg,
            'log_type'      => '',
            'api_type'      => 'request',
            'memo'          => '',
            'original_bn'   => $primary_bn,
            'createtime'    => time(),
            'last_modified' => time(),
            'msg_id'        => $result['msg_id'],
        );

        $apilogModel->insert($logsdf);

        return $result;
    }

    /**
     * 异步请求回调
     *
     * @return void
     * @author 
     **/
    public function callback($result)
    {
        if (!is_object($result)) return true;

        $callback_params = $result->get_callback_params();
        $rsp             = $result->get_status();
        $msg_id          = $result->get_msg_id();
        $msg             = $result->get_result();
        $response        = $result->get_response();

        $status = $rsp == 'succ' ? 'success' : 'fail';
        $log_id = $callback_params['log_id'];
        $msg = var_export($response,true);
        if(isset($msg{2048})) { //当返回结果大于2KB时，日记中不写结果
            $msg = $rsp == 'succ' ? '成功' : '失败';
        }

        $apilogModel = app::get('ome')->model('api_log');
        $apilogModel->update(array('status'=>$status,'msg'=>$msg),array('log_id'=>$log_id));


        return array('rsp'=>$rsp, 'res'=>$msg, 'msg_id'=>$msg_id);
    }

   
    #请求SHOPEX中心
    public function center_call($method, $params, $time_out = 10, $http_method = 'POST')
    {
        $url = MATRIX_RELATION_URL;
        $configParams = $this->__config->get_query_params($method, $params);
        $sys_params = array(
            'app'          => $method,
            'certi_id'     => $configParams['certi_id'],
            'from_node_id' => $configParams['from_node_id'],
            'from_api_v'   => $configParams['from_api_v'],
            'to_node_id'   => $configParams['to_node_id'],
            'to_api_v'     => $configParams['to_api_v'],
            'v'            => $configParams['from_api_v'],
            'node_type'    => $configParams['node_type'],
            'timestamp'    => date('Y-m-d H:i:s',time()),
            'format'       => 'json',
        );
        $query_params = array_merge($sys_params,$params);
        $query_params['certi_ac'] = self::licence_sign($query_params,'ome');
        if ($http_method == 'POST'){
            $http = kernel::single('base_httpclient');
            $response = $http->set_timeout($time_out)->post($url,$query_params);
            $response = json_decode($response,true);
            $rsp = array('rsp'=>'fail','msg'=>'','data'=>'');
            if (!isset($response['res'])){
                $rsp['msg'] = '请求超时';
            }else{
                $rsp['rsp'] = $response['res'];
                $rsp['msg'] = $response['msg'];
                $rsp['data'] = $response['info'];
            }
            return $rsp;
        }else{
            $query_str = array();
            foreach ($query_params as $key=>$value){
                $query_str[] = $key.'='.$value;
            }
            $query_str = implode('&',$query_str);
            $src = $url.'?'.$query_str;
            header('Location:'.$src);
            exit;
        }
    }
    /**
     * licence生成加密串
     * @access public
     * @param $params
     * @return String
     */
    static public function licence_sign($params){
        $str   = '';
        ksort($params);
        foreach($params as $key => $value){
            $str.=$value;
        }
        $token = base_certificate::token();

        return md5($str.$token);
    }

     /**
     * 放mq后台执行请求
     *
     * @return void
     * @author 
     **/
    public function caller_into_mq($method,$channel_type,$channel_id,$params,$queue=false)
    {
        if (!defined('SAAS_API_MQ') 
            || SAAS_API_MQ != 'true' 
            || $queue != true
            ) {
            return false;
        }

        $data = array();
        $data['spider_data']['url'] = kernel::openapi_url('openapi.autotask','service');

        $push_params = array(
            'method'       => $method,
            'channel_type' => $channel_type,
            'channel_id'   => $channel_id,
            'params'       => json_encode($params),
            'log_id'       => uniqid(),
            'task_type'    => 'autoretryapi',
        );
        $push_params['sign'] =  taskmgr_rpc_sign::gen_sign($push_params);

        $postAttr = array();
        foreach ($push_params as $key => $val) {
            $postAttr[] = $key . '=' . urlencode($val);
        }

        $data['spider_data']['params']    = empty($postAttr) ? '' : join('&', $postAttr);
        $data['relation']['to_node_id']   = base_shopnode::node_id('ome');
        $data['relation']['from_node_id'] = '0';
        $data['relation']['tid']          = $push_params['log_id'];
        $data['relation']['to_url']       = $data['spider_data']['url'];
        $data['relation']['time']         = time();

        $routerKey = 'tg.sys.api.'.$data['nodeId'];

        $message = json_encode($data);
        $mq = kernel::single('base_queue_mq');
        $mq->connect($GLOBALS['_MQ_API_CONFIG'], 'TG_API_EXCHANGE', 'TG_API_QUEUE');
        $mq->publish($message, $routerKey);
        $mq->disconnect();

        return true;
    }
}